iT邦幫忙

2025 iThome 鐵人賽

DAY 20
0
Software Development

30 天精通 C 語言建置與除錯:從 Makefile 到 CMake 跨平台實戰系列 第 20

[Day 20] [make→cmake] 執行人生中第一個CmakeList

  • 分享至 

  • xImage
  •  

PS: 今天我們要重回狗狗迷因了!!
/images/emoticon/emoticon01.gif

今天會學到的

  • 複習用makefile 編譯的方法 (這邊的makefile用小寫跟cmake編出來的做區分)
  • cmake 編出 Makefile
  • 執行人生中第一個cmake

步驟

1. 請先準備下面幾個檔案

  • makefile

# ========= Project =========
TARGET      := app
SRC_DIR     := src
INC_DIR     := inc
BUILD_DIR   := build

SRCS        := $(wildcard $(SRC_DIR)/*.c)
OBJS        := $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SRCS))
DEPS        := $(OBJS:.o=.d)

# ========= Toolchain & Flags =========
CC          ?= gcc

# Preprocess flags (-I/-D), compile flags, link flags
CPPFLAGS    := -I$(INC_DIR) -DAPP_VERSION=\"1.0.0\"
CFLAGS      := -O2 -Wall -Wextra -Wpedantic
LDFLAGS     :=

# DEBUG=1 to enable debug build
ifeq ($(DEBUG),1)
  CFLAGS := -O0 -g3 -Wall -Wextra -Wpedantic
endif

# Auto dependencies (.d files)
DEPFLAGS    := -MMD -MP

# ========= Rules =========
.PHONY: all clean run install uninstall

all: $(BUILD_DIR)/$(TARGET)

$(BUILD_DIR)/$(TARGET): $(OBJS) | $(BUILD_DIR)
	$(CC) $(OBJS) -o $@ $(LDFLAGS)

$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR)
	$(CC) $(CPPFLAGS) $(CFLAGS) $(DEPFLAGS) -c $< -o $@

$(BUILD_DIR):
	@mkdir -p $@

run: all
	./$(BUILD_DIR)/$(TARGET)

# Install to ./dist by default (override with PREFIX=/usr/local)
PREFIX ?= $(CURDIR)/dist
install: all
	@mkdir -p $(PREFIX)/bin
	@mkdir -p $(PREFIX)/include
	@cp -f $(BUILD_DIR)/$(TARGET) $(PREFIX)/bin/
	@cp -rf $(INC_DIR)/. $(PREFIX)/include/

uninstall:
	@rm -f $(PREFIX)/bin/$(TARGET)
	@rm -rf $(PREFIX)/include

clean:
	@rm -rf $(BUILD_DIR) dist

# Include auto-generated dependency files
-include $(DEPS)


  • CmakeList.txt
cmake_minimum_required(VERSION 3.21)
project(C_PROJ VERSION 1.0.0 LANGUAGES C)

# Export compile_commands.json for clangd/clang-tidy
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# C standard
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)

  

# Library from src/dog_meme.c
add_library(dog_meme STATIC
  src/dog_meme.c
)
target_include_directories(dog_meme
  PUBLIC
    ${CMAKE_SOURCE_DIR}/inc
)

# Executable from src/main.c
add_executable(app
  src/main.c
)
target_link_libraries(app PRIVATE dog_meme)
# Target-scoped warnings/defines/includes

target_compile_options(app PRIVATE -Wall -Wextra -Wpedantic)
target_compile_definitions(app PRIVATE APP_VERSION="1.0.0")
target_include_directories(app PRIVATE ${CMAKE_SOURCE_DIR}/inc)

# Install rules

install(TARGETS app RUNTIME DESTINATION bin)
install(DIRECTORY inc/ DESTINATION include)

2. 如何用makefile直接執行

前面幾個章節有提到,其實就只是把makefile 準備好,然後下command 到專案的terminal 就可以直接編譯出執行檔

make

除了make執行編譯之外,還有幾個自己列舉的 .PHONY: all clean run install uninstall
也可以透過下面的指令去出指定的動作

cd C_proj
make           # 編譯到 build/app
make run       # 執行
make clean     # 清理
make install   # 安裝到 ./dist(或 PREFIX=/usr/local)

3. 如何用Cmake執行

Cmake 執行的話,主要會分成兩個步驟:

  • 產生Makefile
  • 執行編譯出來的執行檔
    今天主要會像前幾天的教學一樣,先能夠執行出來結果,在一步一步解析,逐漸看懂cmake在做哪些事情
  • 如果想要先瞭解一下cmake 的指令有哪些,用途是什麼話可以先參考[Day 19]的內容
  • 執行步驟
cd C_proj<專案根目錄>
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug  # 產生Makefilie
cmake --build build -j
./build/app  #執行程式 --> 產生狗狗迷因圖

# 安裝
cmake --install build --prefix ./dist

https://ithelp.ithome.com.tw/upload/images/20250919/20178484lmS7N17dGn.png


上一篇
[Day 19] [make→cmake] 用cmake補足makefile的限制
下一篇
[Day 21] [Cmake]深入解析Cmake, CMakelist.txt, Makefile 的對應關係
系列文
30 天精通 C 語言建置與除錯:從 Makefile 到 CMake 跨平台實戰24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言